<?php
/**
 * UserIdentity class file.
 *
 * @package   components
 * @since     1.0
 * @filesource
 */

/**
 * UserIdentity represents the data needed to identity a user.
 * It contains the authentication method that checks if the provided
 * data can identity the user.
 * 
 * UserIdentity will be used by SiteController.actionLogin() to authenticate 
 * user when user want to log in. 
 */
class UserIdentity extends CUserIdentity
{
	// Add constant variable for displaying login error.
	
	
	/**
	 * @var int - Constent variable representing a kind of error - has no access right, 
	 * when authenticating a user.
	 */
	const ERROR_USER_HAS_NO_ACCESS=10;
	
	
	/**
	 * Authenticates a user.
	 * This function will authenticate username and password given by a user and
	 * authenticate his identity.
	 * This function will set the self::errorCode according to the result of authenticaiton,
	 * and then return true or false for success or fail. 
	 * Note: if the authentication is successful, and error code - self::ERROR_NONE also will
	 * be set to self::errorCode.
	 *
	 * @return boolean whether authentication succeeds.
	 */
	public function authenticate()
	{
		// Get User object based on a given
		$user=User::model()->findByAttributes(array('username'=>$this->username));
		
		// Check if user is found via the given username.
		if($user==NULL){
			// if user is not found in the database, set the error code correspondingly. 
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		}else{
			// if user is found in the database by the given username, some validations should be taken.
			
			// Encrypt the password input by user.
			$hashedPassword=hash('sha512', $this->username.$this->password);
			
			// Check if the input password is same as the password of the found user in database.
			if($user->password!==$hashedPassword){
				// if the password does not match, set the error code correspondingly.
				$this->errorCode=self::ERROR_PASSWORD_INVALID;
			}else{
				// if the login is valid, some procedure should be taken.
				
				// check if user has any access to any organization. 
				// Because, only when the he or she is admin, or has access right to at least one organization,
				// the user is able to login the system. 
				if($user->username=='admin' || $user->organizationWithAccessCount > 0){
					// if the user is admin or has access right, then set the user id.
					$this->setState('id', $user->id);
					// set the error code correspondingly. 
					$this->errorCode=self::ERROR_NONE;
				}else{
					// if the user is not admin, or has no access right to any organization,
					// then he or she is not ablet log in system and set the error code correspondingly.
					$this->errorCode=self::ERROR_USER_HAS_NO_ACCESS;
				}				
			}
		}
		// return if the authenticateion is successful.
		// Because the error code of ERROR_NONE is 0 and others are bigger than 0 and are integer,
		// therefore return !$this->errorCode is true, when there is no error, otherwise false, when there is an error.
		// Please refer to YII framework online documentations for details.
		return !$this->errorCode;
	}
	
	/**
	 * The function will return user id of a UserIdentity instance.
	 * @return integer the ID of the user record
	 */
	public function getId()
	{
		// return the user's id.
		return $this->getState('id');
	}
}